package gp;

import java.util.ArrayList;
import java.util.Stack;

public class Tree {
	Node root;
	int height;
	
	public Tree(Symbol symbol){
		this.root = new Node(symbol, null);
	}
	
	public Tree(Stack<Symbol> symbolsStack){
		this.root = new Node(null, null);
		this.insert(this.root, symbolsStack);
		this.height = this.root.height()-1;
	}

	
	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	/*
	 * Inert nodes in the tree. Symbols
	 */
	private void insert(Node node, Stack<Symbol> symbolsStack){
		node.symbol = (Symbol) symbolsStack.pop();
		int degree = node.symbol.getDegree();
		
		if(degree > 0){
			node.left = new Node(node);
			this.insert(node.left, symbolsStack);
			degree--;
		}
		if(degree > 0){
			node.right = new Node(node);
			this.insert(node.right, symbolsStack);
			degree--;
		}
		if(degree == 0){
			return;
		}
		System.out.println("Degree > 2");
		System.exit(0);
	}
	
	private void get_vector_height(int max_height, int current_height, ArrayList<Symbol> vector, Node node){
		if(current_height == max_height){
			if(max_height < height && node.symbol.degree == 2){
				vector.add(node.symbol);
			}
			else if(max_height < height && node.symbol.degree == 0){
				vector.add(new Symbol(2));
			}
			else if(max_height == height && node.symbol.degree == 0){ //Não faria sentido de qualquer forma haver um grau 2 na folha
				vector.add(node.symbol);
			}
			return;
		}
		
		if(node.left == null){
			int num_empty_symbols = (int) Math.pow(2, max_height - current_height - 1);
			if(max_height == height){	//como é um nó folha o grau é sempre 0 (node.symbol.degree == 0)
				vector.add(node.symbol);
				num_empty_symbols -= 1;
			}
			for(int i = 0; i < num_empty_symbols; i++){
				if(max_height < height)
				{
					vector.add(new Symbol(2));
				}
				else {
					vector.add(new Symbol(0));
				}
			}
		}else{
			get_vector_height(max_height, current_height+1, vector, node.left);
		}

		if(node.right == null){
			int num_empty_symbols = (int) Math.pow(2, max_height - current_height - 1);
			for(int i = 0; i < num_empty_symbols; i++){
				if(max_height < height)
				{
					vector.add(new Symbol(2));
				}
				else {
					vector.add(new Symbol(0));
				}
			}
		}else{
			get_vector_height(max_height, current_height+1, vector, node.right);
		}

		return;
	}
	
	public void get_vector_height(int max_height, ArrayList<Symbol> vector){
		this.get_vector_height(max_height, 0, vector, this.root);
		return;
	}
	
}
